package com.hmyuan.service.impl;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.imageio.ImageIO;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hmyuan.dao.FilesMapper;
import com.hmyuan.domain.Files;
import com.hmyuan.service.FilesService;
import com.hmyuan.util.DateUtil;
import com.hmyuan.util.DictionaryUtil;
import com.hmyuan.util.images.ImgForText;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.request.UploadFileRequest;
import com.qcloud.cos.sign.Credentials;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;

@Service("filesService")
public class FilesServiceImpl implements FilesService {

	@Resource
	FilesMapper filesMapper;
	@Resource
	DictionaryUtil dictionaryUtil;
	
	@Value("#{configProperties['yuantuPathRoot']}")
	String yuantuPathRoot;
	@Value("#{configProperties['waterOfImg']}")
	String waterOfImg;

	@Override
	public PageInfo<Files> selectListByPage(Files files,
			int pageNum, int pageSize) {
		// TODO Auto-generated method stub
		PageHelper.startPage(pageNum, pageSize); // 核心分页代码
		List<Files> list = filesMapper.selectList(files);
		PageInfo<Files> pageInfo = new PageInfo<Files>(list);
		
		return pageInfo;
	}

	@Override
	public Files insertUpload(CommonsMultipartFile upfile) throws IOException {
		String dateString = DateUtil.dateToString(new Date(), "yyyyMM");
		long timestamp = DateUtil.getTimestamp();
		String fileName=upfile.getOriginalFilename();
	    String prefix=fileName.substring(fileName.lastIndexOf("."));
		String filePath = "/img/"+dateString+"/"+timestamp+prefix;
		//创建路径
		 if (!(new File(yuantuPathRoot+dateString).isDirectory())) {
			    new File(yuantuPathRoot+dateString).mkdir();
		 }
		
		//给文件添加水印
		ByteArrayOutputStream os = getBufferedImageByCommonsMultipartFile(upfile);
		
		//将文件写入磁盘
		FileUtils.writeByteArrayToFile(new File(yuantuPathRoot+filePath), os.toByteArray());
		
		Files files = new Files();
		files.setFilename(upfile.getOriginalFilename());
		files.setFilepath(filePath);
		int num = filesMapper.insert(files);
		return files;
	}
	/**
	 *本地文件上传 
	 */
	public String localUpload(CommonsMultipartFile upfile)throws IOException{
		String dateString = DateUtil.dateToString(new Date(), "yyyyMM");
		long timestamp = DateUtil.getTimestamp();
		String fileName=upfile.getOriginalFilename();
	    String prefix=fileName.substring(fileName.lastIndexOf("."));
		String filePath = "/img/"+dateString+"/"+timestamp+prefix;
		//创建路径
		 if (!(new File(yuantuPathRoot+dateString).isDirectory())) {
			    new File(yuantuPathRoot+dateString).mkdir();
		 }
		
		//给文件添加水印
		ByteArrayOutputStream os = getBufferedImageByCommonsMultipartFile(upfile);
		
		//将文件写入磁盘
		FileUtils.writeByteArrayToFile(new File(yuantuPathRoot+filePath), os.toByteArray());
		return filePath;
	}
	
	/**
	 * 给文件添加水印
	 */
	public ByteArrayOutputStream getBufferedImageByCommonsMultipartFile(CommonsMultipartFile upfile)throws IOException{
		//生成水印图片
        ImgForText vCode = new ImgForText(400,60,waterOfImg);
        
        BufferedImage bufferedImage = ImageIO.read(upfile.getInputStream());
        int width = bufferedImage.getWidth();   
        ByteArrayOutputStream os = new ByteArrayOutputStream();  
        //宽度超过1000则进行尺寸压缩
        if(width>1000){
        	// watermark 参数 1.位置 2.水印图片 3.透明度
        	bufferedImage = Thumbnails.of(bufferedImage)
        	.size(1000, 2000)
        	.watermark(Positions.CENTER, vCode.getBuffImg(), 0.25f).asBufferedImage();
        }else{
        	// watermark 参数 1.位置 2.水印图片 3.透明度
        	bufferedImage = Thumbnails.of(bufferedImage)
        	.scale(1.0f)
        	.watermark(Positions.CENTER, vCode.getBuffImg(), 0.25f).asBufferedImage();
        }
        ImageIO.write(bufferedImage, "jpg", os);
        
        return os;
	}
	
	public String qcloudUpload(CommonsMultipartFile upfile) throws IOException{
		String dateString = DateUtil.dateToString(new Date(), "yyyyMM");
		long timestamp = DateUtil.getTimestamp();
		String fileName=upfile.getOriginalFilename();
	    String prefix=fileName.substring(fileName.lastIndexOf("."));
	    //给文件添加水印
	    ByteArrayOutputStream os = getBufferedImageByCommonsMultipartFile(upfile);
	    //获取配置
        Map<String, String> qcloud = dictionaryUtil.checkAndInit("qcloud");
		
		// 设置用户属性, 包括appid, secretId和SecretKey
        // 这些属性可以通过cos控制台获取(https://console.qcloud.com/cos)
        long appId = Long.parseLong(qcloud.get("appId"));
        String secretId = qcloud.get("secretId");
        String secretKey = qcloud.get("secretKey");
        // 设置要操作的bucket
        String bucketName = qcloud.get("bucketName");
        // 初始化客户端配置
        ClientConfig clientConfig = new ClientConfig();
        // 设置bucket所在的区域，比如广州(gz), 天津(tj)
        clientConfig.setRegion(qcloud.get("region"));
        // 初始化秘钥信息
        Credentials cred = new Credentials(appId, secretId, secretKey);
        // 初始化cosClient
        COSClient cosClient = new COSClient(clientConfig, cred);
        // 1. 上传文件(默认不覆盖)
        // 将本地的local_file_1.txt上传到bucket下的根分区下,并命名为sample_file.txt
        // 默认不覆盖, 如果cos上已有文件, 则返回错误
        String cosFilePath = "/img/"+dateString+"/"+timestamp+prefix;
        
        UploadFileRequest uploadFileRequest =
        		new UploadFileRequest(bucketName, cosFilePath, os.toByteArray());
        uploadFileRequest.setEnableShaDigest(false);
        String uploadFileRet = cosClient.uploadFile(uploadFileRequest);
        cosClient.shutdown();
        return cosFilePath;
	}
	
	@Override
	public String qiniuUpload(CommonsMultipartFile upfile) throws IOException {
		// TODO Auto-generated method stub
		String dateString = DateUtil.dateToString(new Date(), "yyyyMM");
		long timestamp = DateUtil.getTimestamp();
		String fileName=upfile.getOriginalFilename();
	    String prefix=fileName.substring(fileName.lastIndexOf("."));
		
	    //给文件添加水印
	    ByteArrayOutputStream os = getBufferedImageByCommonsMultipartFile(upfile);
		//获取配置
        Map<String, String> qiniu = dictionaryUtil.checkAndInit("qiniu");
        //要上传的空间
        String bucketname = qiniu.get("bucketname");
        //上传到七牛后保存的文件名
        String key = "img/"+dateString+"/"+timestamp+prefix;
        //密钥配置
        //设置好账号的ACCESS_KEY和SECRET_KEY
        Auth auth = Auth.create(qiniu.get("ACCESS_KEY"), qiniu.get("SECRET_KEY"));
        
        ///////////////////////指定上传的Zone的信息//////////////////
        //第一种方式: 指定具体的要上传的zone
        //注：该具体指定的方式和以下自动识别的方式选择其一即可
        //要上传的空间(bucket)的存储区域为华东时
        // Zone z = Zone.zone0();
        //要上传的空间(bucket)的存储区域为华北时
        // Zone z = Zone.zone1();
        //要上传的空间(bucket)的存储区域为华南时
        // Zone z = Zone.zone2();

        //第二种方式: 自动识别要上传的空间(bucket)的存储区域是华东、华北、华南。
        Zone z = Zone.autoZone();
        Configuration c = new Configuration(z);

        //创建上传对象
        UploadManager uploadManager = new UploadManager(c);
        
        //调用put方法上传
        //Response res = uploadManager.put(FilePath, key, getUpToken());
        Response res = uploadManager.put(new ByteArrayInputStream(os.toByteArray()), key, auth.uploadToken(bucketname), null, null);
        JSONObject jo = (JSONObject) JSONObject.parse(res.bodyString());
		return "/"+(String) jo.get("key");
	}
	
	@Override
	public byte[] filesShowById(Long id) {
		// TODO Auto-generated method stub
		if(id==null) return null;
		Files files = filesMapper.selectByPrimaryKey(id);
		if(files==null||files.getFilepath()==null) return null;
		
		try {
			File file = new File(yuantuPathRoot+files.getFilepath());
			if(file.exists()){
				return FileUtils.readFileToByteArray(file);
			}else{
				return null;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	@Override
	public Files selectByPrimaryKey(Long id) {
		// TODO Auto-generated method stub
		return filesMapper.selectByPrimaryKey(id);
	}


	@Override
	public boolean deletefilesById(Long id) {
		// TODO Auto-generated method stub
		Files files = selectByPrimaryKey(id);
		if(files!=null){
			FileUtils.deleteQuietly(new File(yuantuPathRoot+files.getFilepath()));
		}
		int num = filesMapper.deleteByPrimaryKey(id);
		return num==1?true:false;
	}

	@Override
	public boolean insert(Files files) {
		// TODO Auto-generated method stub
		int num = filesMapper.insert(files);
		return num==1?true:false;
	}

	@Override
	public String fileUpload(CommonsMultipartFile file) throws IOException {
		// TODO Auto-generated method stub
		//获取当前配置的文件存储位置
		String fileConfig = dictionaryUtil.checkAndInit("baseInfo").get("fileConfig");
		if("qiniu".equals(fileConfig)){
			return qiniuUpload(file);
		}else if("qcloud".equals(fileConfig)){
			return qcloudUpload(file);
		}else if("local".equals(fileConfig)){
			return "/files/filesShow"+localUpload(file);
		}else{
			return null;
		}
	}

	@Override
	public byte[] filesShow(String path) {
		// TODO Auto-generated method stub
		try {
			File file = new File(yuantuPathRoot+"/"+path);
			if(file.exists()){
				return FileUtils.readFileToByteArray(file);
			}else{
				return null;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	
}
